import XCTest
@testable import JAZCommandParse

final class ParameterValueTests: XCTestCase {
    func testExample() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct
        // results.
        let parse = CommandParse(description: "Hellow")
        XCTAssertEqual(parse.description, "Hellow")
    }
    
    func testParseIntValue() throws {
        var value: Int = 0
        let parse = generateValuePointerParse(value: &value)
        try parse.parseValue(withReversed: ["\(Int.max)"])
        XCTAssertEqual(value, Int.max)
        try parse.parseValue(withReversed: ["0"])
        XCTAssertEqual(value, 0)
        try parse.parseValue(withReversed: ["\(Int.min)"])
        XCTAssertEqual(value, Int.min)
        value = 0
        for i in 1..<10 {
            do {
                let parseValue = UInt64(Int.max) + 100 * UInt64(i)
                try parse.parseValue(withReversed: ["\(parseValue)"])
                XCTFail("Parse \(parseValue) Should Failed")
            } catch {
                XCTAssertEqual(value, 0, "Parse failed, value should not change")
            }
            do {
                let parseValue = UInt64(Int.max) + 100 * UInt64(i)
                try parse.parseValue(withReversed: ["-\(parseValue)"])
                XCTFail("Parse -\(parseValue) Should Failed")
            } catch {
                XCTAssertEqual(value, 0, "Parse failed, value should not change")
            }
        }
    }
    
    func testParseInt8Value() throws {
        var value: Int8 = 0
        let parse = generateValuePointerParse(value: &value)
        try parse.parseValue(withReversed: ["\(Int8.max)"])
        XCTAssertEqual(value, Int8.max)
        try parse.parseValue(withReversed: ["0"])
        XCTAssertEqual(value, 0)
        try parse.parseValue(withReversed: ["\(Int8.min)"])
        XCTAssertEqual(value, Int8.min)
        value = 0
        for i in 1..<10 {
            do {
                let parseValue = UInt64(Int.max) + 100 * UInt64(i)
                try parse.parseValue(withReversed: ["\(parseValue)"])
                XCTFail("Parse \(parseValue) Should Failed")
            } catch {
                XCTAssertEqual(value, 0, "Parse failed, value should not change")
            }
            do {
                let parseValue = UInt64(Int.max) + 100 * UInt64(i)
                try parse.parseValue(withReversed: ["-\(parseValue)"])
                XCTFail("Parse -\(parseValue) Should Failed")
            } catch {
                XCTAssertEqual(value, 0, "Parse failed, value should not change")
            }
        }
    }
    
    func testParseInt16Value() throws {
        
    }
    
    func generateValuePointerParse<T>(value: ParameterValue.ValuePointer<T>) -> ParameterValue {
        return ParameterValue(key: "", miniKey: "", type: T.self, value: value, description: "")
    }
    
    func generateCallBackParse<T>(value: @escaping ParameterValue.CallBackClosure<T>) -> ParameterValue {
        return ParameterValue(key: "", miniKey: "", type: T.self, value: value, description: "")
    }
    
    func generateThrowCallBackParse<T>(value: @escaping ParameterValue.CallBackThrowsClosure<T>) -> ParameterValue {
        return ParameterValue(key: "", miniKey: "", type: T.self, value: value, description: "")
    }
    
    func generateRCallBackParse(value: @escaping ParameterValue.CallBackRBoolClosure) -> ParameterValue {
        return ParameterValue(key: "", miniKey: "", type: Any.self, value: value, description: "")
    }

    static var allTests = [
        ("testExample", testExample),
    ]
}
